package com.dy.yunying.biz.controller.znfx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dy.yunying.api.constant.Constant;
import com.dy.yunying.api.datacenter.export.AdExportDataAnalysisVO;
import com.dy.yunying.api.req.znfx.AdPlanAnalyseReq;
import com.dy.yunying.api.req.znfx.AdPlanOverviewDto;
import com.dy.yunying.api.resp.znfx.AdPlanDataExportRes;
import com.dy.yunying.api.utils.CheckUtils;
import com.dy.yunying.biz.service.znfx.AdPlanAnalyseService;
import com.dy.yunying.biz.utils.DateUtils;
import com.dy.yunying.biz.utils.ExportAlibabaUtils;
import com.dy.yunying.biz.utils.ExportUtils;
import com.dy.yunying.biz.utils.MapUtils;
import com.google.api.client.util.Lists;
import com.pig4cloud.pig.common.core.exception.BusinessException;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author chenxiang
 * @className AdPlanController
 * @date 2023-3-22 10:59
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/planAnalyse")
@Api(value = "planAnalyse", tags = "计划分析")
@Slf4j
public class AdPlanAnalyseController {

	private final AdPlanAnalyseService adPlanAnalyseService;

	@ApiOperation(value = "计划汇总", notes = "计划汇总")
	@RequestMapping("/collect")
	public R collect(@Valid @RequestBody AdPlanAnalyseReq record) {
		try {
			R result = this.checkParam(record);
			if (0 != result.getCode()){
				return result;
			}
			return adPlanAnalyseService.adPlanCollect(record);
		} catch (Exception e) {
			log.error("计划分析-接口：{}", e.getMessage());
			return R.failed("接口异常，请联系管理员");
		}
	}

	@ApiOperation(value = "计划图表", notes = "计划图表")
	@RequestMapping("/chartData")
	public R chartData(@Valid @RequestBody AdPlanAnalyseReq record) {
		try {
			R result = this.checkParam(record);
			if (0 != result.getCode()){
				return result;
			}
			return adPlanAnalyseService.chartData(record);
		} catch (Exception e) {
			log.error("计划分析-接口：{}", e.getMessage());
			return R.failed("接口异常，请联系管理员");
		}
	}

	/**
	 * 导出
	 * @param record
	 * @param response
	 */
	@RequestMapping("/export")
	@SysLog("计划分析报表导出")
	public void export(@Valid @RequestBody AdPlanOverviewDto record, HttpServletResponse response){
		try {
			R result = this.checkParam(record);
			if (0 != result.getCode()){
				throw new BusinessException(result.getMsg());
			}
			String columns = (1 == record.getType() ? "adid,adidName" : "period") + ",rudeCost,cost,clickRatio,regRatio,uuidnums,usrnamenums,activationRatio,createRoleCount,createRoleRate,certifiedCount,notCertifiedCount,certifiedRate,deviceCose,paydevice1,payCose1,regPayRatio,payNum1,payNum7,newPayFee,newPayGivemoney,regarpu,payarppu,paydeviceAll,payCoseAll,totalPayRate,totalPayFee,totalPayGivemoney,roi1,allRoi,retention2Ratio,payedRetention2,weekRoi,monthRoi,weekPayFee,monthPayFee,periodPayCount,periodPayFee,periodPayRate,periodROI,activeNum,activePayCount,activePayRate,payNum,activePayFee,activePayGivemoney,actarpu,activearppu,deduplicateDeviceCount,returnDeviceCount,duplicateDeviceCount";

			List<AdPlanDataExportRes> resultList = adPlanAnalyseService.exportDataList(record);

			List<Map<String, Object>> resultListMap = MapUtils.objectsToMaps(resultList);

			ExportUtils.spliceSuffix(resultListMap, Constant.PERCENT, Constant.DEFAULT_VALUE,
					"activationRatio", "clickRatio", "regPayRatio", "regRatio", "retention2Ratio", "payedRetention2", "allRoi",
					"monthRoi", "weekRoi", "roi1", "createRoleRate", "certifiedRate", "activePayRate", "periodPayRate", "periodROI", "totalPayRate");

			JSONArray array = JSONArray.parseArray(JSON.toJSONString(resultListMap));

			List<AdPlanDataExportRes> list = Lists.newArrayList();
			for (int i = 0; i < array.size(); i++) {
				JSONObject jsonObject = array.getJSONObject(i);
				AdPlanDataExportRes detail = JSON.parseObject(String.valueOf(jsonObject), AdPlanDataExportRes.class);
				list.add(detail);
			}

			String exportName = 1 == record.getType() ? "计划属性分析报表" : "计划用户分析报表";

			String fileName = URLEncoder.encode(exportName + DateUtils.getCurrentTimeNoUnderline(), "UTF-8").replaceAll("\\+", "%20");

			ExportAlibabaUtils.exportExcelData(response, exportName, fileName, columns, list, AdPlanDataExportRes.class);
		} catch (Exception e) {
			log.error(">>>计划分析报表导出异常：{}", e);
			throw new BusinessException(e.getMessage());
		}
	}

	/**
	 * 校验入参
	 * @param record
	 * @return
	 */
	private R checkParam(AdPlanAnalyseReq record){
		final String firstRoiMin = record.getFirstRoiMin();
		final String firstRoiMax = record.getFirstRoiMax();
		final String threeRoiMin = record.getThreeRoiMin();
		final String threeRoiMax = record.getThreeRoiMax();
		final String sevenRoiMin = record.getSevenRoiMin();
		final String sevenRoiMax = record.getSevenRoiMax();
		final String fifteenRoiMin = record.getFifteenRoiMin();
		final String fifteenRoiMax = record.getFifteenRoiMax();
		final String thirtyRoiMin = record.getThirtyRoiMin();
		final String thirtyRoiMax = record.getThirtyRoiMax();
		final String regCostMin = record.getRegCostMin();
		final String regCostMax = record.getRegCostMax();
		final String firstPayCostMin = record.getFirstPayCostMin();
		final String firstPayCostMax = record.getFirstPayCostMax();
		final String totalPayCostMin = record.getTotalPayCostMin();
		final String totalPayCostMax = record.getTotalPayCostMax();

		if ((StringUtils.isNotBlank(firstRoiMin) && !CheckUtils.checkMoney(firstRoiMin))
				|| (StringUtils.isNotBlank(firstRoiMax) && !CheckUtils.checkMoney(firstRoiMax))){
			return R.failed("请输入正确的首日ROI");
		}
		if ((StringUtils.isNotBlank(threeRoiMin) && !CheckUtils.checkMoney(threeRoiMin))
				|| (StringUtils.isNotBlank(threeRoiMax) && !CheckUtils.checkMoney(threeRoiMax))){
			return R.failed("请输入正确的3日ROI");
		}
		if ((StringUtils.isNotBlank(sevenRoiMin) && !CheckUtils.checkMoney(sevenRoiMin))
				|| (StringUtils.isNotBlank(sevenRoiMax) && !CheckUtils.checkMoney(sevenRoiMax))){
			return R.failed("请输入正确的7日ROI");
		}
		if ((StringUtils.isNotBlank(fifteenRoiMin) && !CheckUtils.checkMoney(fifteenRoiMin))
				|| (StringUtils.isNotBlank(fifteenRoiMax) && !CheckUtils.checkMoney(fifteenRoiMax))){
			return R.failed("请输入正确的15日ROI");
		}
		if ((StringUtils.isNotBlank(thirtyRoiMin) && !CheckUtils.checkMoney(thirtyRoiMin))
				|| (StringUtils.isNotBlank(thirtyRoiMax) && !CheckUtils.checkMoney(thirtyRoiMax))){
			return R.failed("请输入正确的30日ROI");
		}
		if ((StringUtils.isNotBlank(regCostMin) && !CheckUtils.checkMoney(regCostMin))
				|| (StringUtils.isNotBlank(regCostMax) && !CheckUtils.checkMoney(regCostMax))){
			return R.failed("请输入正确的注册成本");
		}
		if ((StringUtils.isNotBlank(firstPayCostMin) && !CheckUtils.checkMoney(firstPayCostMin))
				|| (StringUtils.isNotBlank(firstPayCostMax) && !CheckUtils.checkMoney(firstPayCostMax))){
			return R.failed("请输入正确的首日付费成本");
		}
		if ((StringUtils.isNotBlank(totalPayCostMin) && !CheckUtils.checkMoney(totalPayCostMin))
				|| (StringUtils.isNotBlank(totalPayCostMax) && !CheckUtils.checkMoney(totalPayCostMax))){
			return R.failed("请输入正确的累计付费成本");
		}
		return R.ok();
	}
}
